home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 4329 < prev    next >
Encoding:
Text File  |  1996-08-06  |  2.2 KB  |  54 lines

  1. Path: news.th-darmstadt.de!news!enno
  2. From: enno@inferenzsysteme.informatik.th-darmstadt.de (Enno Sandner)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Q: Good C++ UNDO Design
  5. Date: 29 Jan 1996 19:54:15 GMT
  6. Organization: Fachbereich Informatik, TH Darmstadt
  7. Distribution: world
  8. Message-ID: <ENNO.96Jan29205415@kitz.inferenzsysteme.informatik.th-darmstadt.de>
  9. References: <4eit9g$c6j@news1.halcyon.com>
  10. NNTP-Posting-Host: kitz.intellektik.informatik.th-darmstadt.de
  11. In-reply-to: riston@coho.halcyon.com's message of 29 Jan 1996 16:40:16 GMT
  12.  
  13. In article <4eit9g$c6j@news1.halcyon.com> riston@coho.halcyon.com (Michael D. Riston) writes:
  14.  
  15.    I have been charged with designing an undo mechanism for a large graphical
  16.    Windows (32bit) application.  This application is the classic 'draw a 
  17.    shape' program (box, circle, line, OLE object, or whatever).   I would like 
  18.    to know if anybody has any elegant designs for handling undo operations.  I 
  19.    am working with Visual C++ 4.0 and MFC for the implementation.  I
  20.    am well versed in C++.
  21.  
  22. A neat solution to this problem is the 'Command' pattern as described in
  23. the 'Design Patterns' book. The main idea is to encapsulate the necessary
  24. steps to perform a specific behavior in objects that conform to an unique
  25. interface. The interface provides the services 'Do' and 'Undo'. It is
  26. represented by the abstract 'Command' class:
  27.  
  28.         class Command {
  29.           public:
  30.             virtual ~Command() {}
  31.             virtual void Do()=0;
  32.                     virtual void Undo()=0;
  33.                 };
  34.  
  35. Every operation that affects the graphical appearence must have its counter-
  36. part that reverses the operation and both operations should be encapsulated
  37. in a subclass of 'Command'. For example a circle may look like:
  38.  
  39.         class CircleCommand : public Command {
  40.           public:
  41.            CircleCommand(Painter& p,int x,int y,int r) : 
  42.             p_(p), x_(x), y_(y), r_(r) {}
  43.            void Do() { p_.DrawCircle(x_,y_,r_); }
  44.            void Undo() { p_.RemoveCircle(x_,y_,r_); }
  45.         };
  46.  
  47. Moving a graphical object is another example for an operation that should
  48. be wrapped.
  49. Finally you need a manager to register the commands. The manager maintains a
  50. finite command history and allows you to move backwards and forwards in the
  51. history. The former results in undoing the latter in executing the command.
  52.  
  53.     Enno
  54.